import * as FS from 'fs';
import path from 'path';
 
import { expect } from '@jest/globals';
import * as compressing from 'compressing';
import fse from 'fs-extra';
 
import { initExecuteCommand, runHvigorAsync } from '../../common/common';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  IsEnable,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType,
  SignType,
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import { TestTaskOption, TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';
 
const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API10,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.NativeC,
  },
  modulesOption: {
    [ModuleTemplateType.SharedLibraryWithC]: 1,
  },
};
 
const testTaskOption: TestTaskOption = TestTaskOptionBuilder.builder().caseLevel(CaseLevel.L2).sign(SignType.NoSign).ohpmInstall(IsEnable.Enable).build();
 
const testCaseFun: TestCaseFun = async (project, taskConfig, record) => {
  const projectRootPath = project.projectRootPath();
  const entryPath = project.getModule('entry').moduleRootPath();
  const libraryPath = project.getModule('shareNativeCLibrary').moduleRootPath();
 
  // 1、 一个工程，有1个hsp模块 ，entry 模块 名称分别是 shareNativeCLibrary 和 entry
  const hspResult = await runHvigorAsync(
    projectRootPath,
    initExecuteCommand({
      mode: 'module',
      product: 'default',
      tasks: 'assembleHsp',
      daemon: false,
    }),
  );
  expect(hspResult.stdout).toContain('BUILD SUCCESSFUL');
 
  // 2、获取到so 的路径
  const hspSoFilePath = path.resolve(libraryPath,
    'build', 'default', 'intermediates', 'libs', 'default', 'arm64-v8a', 'libshareNativeCLibrary.so');
 
  expect(fse.existsSync(hspSoFilePath)).toEqual(true);
 
  // entry 下 要存放so 的路径
  const entrySoSymlinkPath = path.resolve(entryPath,
    'libs', 'arm64-v8a', 'libshareNativeCLibrary.so');
 
  // 检查并创建目录
  const entrySoDir = path.dirname(entrySoSymlinkPath);
  if (!fse.existsSync(entrySoDir)) {
    fse.mkdirSync(entrySoDir, { recursive: true });
  }
  // 3、创建软连接，把 hsp 中的 so 软连到 har2里 的libs 目录里面
  // 创建软链接， ide需要用管理员权限打开，才能正常创建软连
  FS.symlink(hspSoFilePath, entrySoSymlinkPath, 'file', (err) => {
    if (err) {
      console.error('创建软链接时出错: 用例不需要再执行了, 如果是 operation not permitted 报错, 需要用管理员打开ide 来执行。', err);
    }
  });
 
  // 如果创建不出来软连，就不需要再继续执行用例了。
  if (!fse.existsSync(entrySoSymlinkPath)) {
    return;
  }
 
  // 构建hap
  const assembleHapResult = await runHvigorAsync(
    projectRootPath,
    initExecuteCommand({
      mode: 'module',
      product: 'default',
      tasks: 'assembleHap',
      daemon: false,
    }),
  );
  record.addStep('step', assembleHapResult);
  expect(assembleHapResult.stdout).toContain('BUILD SUCCESSFUL');
 
  // 检查hap 中 有没有打进去软连接so
  // // 查看hap包是否生成
  const buildHapDir = path.resolve(entryPath, 'build', 'default', 'outputs', 'default');
  const hapPath = path.resolve(buildHapDir, 'entry-default-unsigned.hap');
  expect(await fse.pathExists(hapPath)).toBe(true);
  //
  // 解压 hap 包
  await compressing.zip.uncompress(hapPath, buildHapDir);
 
  // so 所在的目录， 判断软连接的so 在不在
  const hspSoDir = path.resolve(buildHapDir, 'libs', 'arm64-v8a', 'libshareNativeCLibrary.so');
  expect(fse.existsSync(hspSoDir)).toBe(true);
};
 
TestCaseBuilder.builder()
  .caseName('DTS2024101927230')
  .description('软链接打包到hap中的用例')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(testTaskOption)
  .testFun(testCaseFun)
  .load();
